package com.ibm.crl.sb.thread.others.comsumer;

import java.util.concurrent.Semaphore;

/**
 * 仓库
 * 
 * @author 老紫竹(laozizhu.com)
 */
class Warehouse {
	// 非满锁
	private final Semaphore notFull;
	// 非空锁
	private final Semaphore notEmpty;
	// 核心锁
	private final Semaphore mutex;
	// 库存容量
	private final Object[] items;
	int putptr = 0, takeptr = 0, count = 0;

	public Warehouse(int max) {
		notFull = new Semaphore(max);
		notEmpty = new Semaphore(0);
		mutex = new Semaphore(1);
		items = new Object[max];
	}

	/**
	 * 把商品放入仓库.<br>
	 * 
	 * @param x
	 * @throws InterruptedException
	 */
	public void put(Object x) throws InterruptedException {
		// 保证非满
		notFull.acquire();
		// 保证不冲突
		mutex.acquire();
		try {
			// 增加库存
			items[putptr] = x;
			if (++putptr == items.length)
				putptr = 0;
			++count;
		} finally {
			// 退出核心区
			mutex.release();
			// 增加非空信号量，允许获取商品
			notEmpty.release();
		}
	}

	/**
	 * 从仓库获取商品
	 * 
	 * @return
	 * @throws InterruptedException
	 */
	public Object take() throws InterruptedException {
		// 保证非空
		notEmpty.acquire();
		// 核心区
		mutex.acquire();
		try {
			// 减少库存
			Object x = items[takeptr];
			if (++takeptr == items.length)
				takeptr = 0;
			--count;
			return x;
		} finally {
			// 退出核心区
			mutex.release();
			// 增加非满的信号量，允许加入商品
			notFull.release();
		}
	}
}